package ar.pegasus.webcam;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Image;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;

import javax.media.Buffer;
import javax.media.CannotRealizeException;
import javax.media.CaptureDeviceInfo;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.cdm.CaptureDeviceManager;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.RGBFormat;
import javax.media.format.VideoFormat;
import javax.media.format.YUVFormat;
import javax.media.util.BufferToImage;
import javax.swing.JMenu;
import javax.swing.JPanel;

import ar.pegasus.componentes.error.ErrorDialog;
import ar.pegasus.framework.util.StringUtil;

/**
 *
 * @author oarias
 */
public class Dispositivos {

    private IFrmCapturaImagen padre;
    @SuppressWarnings("rawtypes")
	private Vector listaDispositivos = null;
    
    private Player player;

    public Dispositivos(IFrmCapturaImagen padre){
        this.padre=padre;
    }

    @SuppressWarnings("rawtypes")
	public String verInfoDispositivos(){
      String rpta="";
      Vector listaDispositivos = null;
      //Buscamos los dispositivos instalados
      listaDispositivos = getListaDispositivos();
      
      Iterator it = listaDispositivos.iterator();
      while (it.hasNext()){
        CaptureDeviceInfo cdi = (CaptureDeviceInfo)it.next();
        rpta+=cdi.getName()+"\n";
      }
      if(!StringUtil.isNullOrEmpty(rpta))
          rpta="Dispositivos detectados:\n\n"+rpta;
      else
          rpta="Sin Dispositivos Detectados";
      
      return rpta;
    }

    @SuppressWarnings("rawtypes")
	private Vector getListaDispositivos() {
    	if(listaDispositivos == null){
	        listaDispositivos = CaptureDeviceManager.getDeviceList(new VideoFormat(VideoFormat.RGB));
	        if(listaDispositivos.isEmpty()){
//	      	  logger.info("No hay dispositivos.");
	        }
    	}
        
		return listaDispositivos;
	}

	@SuppressWarnings("rawtypes")
	public void detectarDispositivos(JMenu dispositivos){
      Vector listaDispositivos = null;
      //Buscamos los dispositivos instalados
      listaDispositivos = CaptureDeviceManager.getDeviceList();
      
      Iterator it = listaDispositivos.iterator();

      String nombre="";
      while (it.hasNext()){
          CaptureDeviceInfo cdi = (CaptureDeviceInfo)it.next();
          nombre=cdi.getName(); // Obtiene el nombre del Dispositivo Detectado
          
          if(nombre.indexOf("Image")!=-1){
              JMenu menuFormato=new JMenu(nombre);
              JMenuFormato tamanios=null;
              CaptureDeviceInfo dev = CaptureDeviceManager.getDevice(nombre);
              Format[] cfmts = dev.getFormats();

              for(int i=0; i<cfmts.length;i++){
                  if(cfmts[i].getEncoding().compareTo("yuv")==0)
                  {tamanios=new JMenuFormato(cfmts[i].getEncoding()+" "+
                          ((YUVFormat)cfmts[i]).getSize().width+"x"+
                          ((YUVFormat)cfmts[i]).getSize().height,
                          ((YUVFormat)cfmts[i]).getSize().width,
                          ((YUVFormat)cfmts[i]).getSize().height,
                          padre,
                          padre.getPanelWebCam());
                  }
                  else if(cfmts[i].getEncoding().compareTo("rgb")==0){
                	  tamanios=new JMenuFormato(cfmts[i].getEncoding()+" "+
                          ((RGBFormat)cfmts[i]).getSize().width+"x"+
                          ((RGBFormat)cfmts[i]).getSize().height,
                          ((RGBFormat)cfmts[i]).getSize().width,
                          ((RGBFormat)cfmts[i]).getSize().height,
                          padre,
                          padre.getPanelWebCam());
                  }
                  menuFormato.add(tamanios);
              }
              dispositivos.add(menuFormato);
          }
      }
    }

	public void stop() {
		if (player != null) {
			player.stop();
			player.close();
			player.deallocate();
			player = null;
		}
	}
	
    public void MuestraWebCam(JPanel panelCam,String dispositivo,String FormatoColor)
    {
        if(player != null)
            return;
        
        CaptureDeviceInfo dev = CaptureDeviceManager.getDevice(dispositivo);
        
        //obtengo el locator del dispositivo
        try {
        	MediaLocator loc = dev.getLocator();
            player = Manager.createRealizedPlayer(loc);
        } catch (IOException ex) {
        	String mensaje = "Error #1. No se pudo conectar a la salida de la aplicación.";
			new ErrorDialog(ErrorDialog.ERR_APLICACION, mensaje, "Verifique que ya no haya otra aplicación usando la webcam").setVisible(true);
        	System.exit(-1);
        } catch (NoPlayerException ex) {
        	String mensaje = "Error #2. No se pudo detectar una camara.";
			new ErrorDialog(ErrorDialog.ERR_APLICACION, mensaje, "Verifique que la webcam se encuentre conectada a la PC. Si no es asi, " +
																 "conecte una webcam e intente de nuevo. Caso contrario reinicie la PC y reintente").setVisible(true);
        	System.exit(-2);
        } catch (CannotRealizeException ex) {
        	String mensaje = "Error #3. No se pudo detectar una camara.";
			new ErrorDialog(ErrorDialog.ERR_APLICACION, mensaje," cierre la aplicación y reintente").setVisible(true);
        	System.exit(-3);
        } catch (NullPointerException e) {
        	String mensaje = "Error #4. No se pudo detectar una camara.";
        	String detalle = "Debe instalar primero el Java Media Framework que permite el trabajo con Webcam. " +
        					 " Una vez instalado JMF, ejecute la opción de registrar dispositivos (JMF Registry)" +
        					 " Si ya está instalado, verifique que el archivo 'JMF.properties' esté apropiadamente instalado en el directorio " +
        					 " de la aplicacion antes de continuar. ";
			new ErrorDialog(ErrorDialog.ERR_APLICACION, mensaje,detalle).setVisible(true);
        	System.exit(-4);
		}
        player.start();

        try {
            // esto lo saqué del foro jmf de Sun, hay que "parar un poco la aplicacion"
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
//            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        Component comp;

        if ((comp = player.getVisualComponent())!= null)
        {
          // mostramos visualmente el reproductor          
          panelCam.add(comp,BorderLayout.CENTER);
          padre.pack();
        }
    }

    public Image CapturaFoto(){
        Image img=null;
        FrameGrabbingControl fgc = (FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
        if(fgc == null){
        	return null;
        }
        Buffer buf = fgc.grabFrame();
        // creamos la imagen awt
        BufferToImage btoi = new BufferToImage((VideoFormat)buf.getFormat());
        img = btoi.createImage(buf);
        
//        liberarPlayer();
    	return img;        
     }

	public void liberarPlayer() {
		if(player == null) return;
        player.stop();
        player.close();
	}
}